package com.zbkj.client.task;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zbkj.client.config.WebSocketSessionManager;
import com.zbkj.client.enums.WebSocketEventType;
import com.zbkj.client.service.DigitalPersonService;
import com.zbkj.client.vo.CustomVoiceCjVo;
import com.zbkj.common.model.client.digital.CustomVoice;
import com.zbkj.service.service.CustomVoiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class CustomVoiceStatusUpdateTask {
    @Resource
    private ThreadPoolTaskScheduler taskScheduler;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private CustomVoiceService customVoiceService;
    @Resource
    private DigitalPersonService digitalPersonService;

    @Value("${digital-person.url}")
    private String digitalPersonUrl;

    @Autowired
    private CustomVoiceUrlUpdateTask customVoiceUrlUpdateTask;

    @Autowired
    private WebSocketSessionManager webSocketSessionManager;

    private final String customVoiceDetailUrl = "/open/v1/customised_audio";
    private final ObjectMapper objectMapper = new ObjectMapper();

    public void start(String linkId) {
        schedule(linkId, 0);
    }

    private void schedule(String linkId, int retryCount) {
        long delay = 60 * 1000; // 1分钟
        taskScheduler.schedule(() -> {
            try {
                doTask(linkId, retryCount);
            } catch (Exception e) {
                log.error("定时任务-定制声音定时任务异常", e);
            }
        }, new Date(System.currentTimeMillis() + delay));
    }

    private void doTask(String linkId, int retryCount) {
        CustomVoice customVoice = customVoiceService.lambdaQuery()
                .eq(CustomVoice::getLinkId, linkId)
                .one();
        if (customVoice == null) {
            log.warn("定时任务-未找到定制声音记录，linkId={}", linkId);
            return;
        }
        if (customVoice.getIsDel() != null && customVoice.getIsDel() == 1) {
            log.info("定时任务-定制声音已被删除，linkId={}", linkId);
            return;
        }
        if (customVoice.getStatus() != null && customVoice.getStatus() != 1) {
            log.info("定时任务-定制声音已更新过，linkId={}", linkId);
            return;
        }

        // 拉取蝉镜接口
        String accessToken = digitalPersonService.getAccessToken();
        String url = digitalPersonUrl + customVoiceDetailUrl + "?id=" + linkId;
        HttpHeaders headers = new HttpHeaders();
        headers.set("access_token", accessToken);
        HttpEntity<Void> entity = new HttpEntity<>(headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        String body = response.getBody();
        if (body == null) {
            log.warn("定时任务-蝉镜返回空数据，linkId={}", linkId);
            return;
        }
        try {
            JsonNode root = objectMapper.readTree(body);
            int code = root.path("code").asInt();
            if (code != 0) {
                log.warn("定时任务-蝉镜返回code!=0，linkId={}, code={}, msg={}", linkId, code, root.path("msg").asText());
                schedule(linkId, retryCount + 1);
                return;
            }
            JsonNode dataNode = root.path("data");
            if (dataNode.isMissingNode() || dataNode.isNull()) {
                log.warn("定时任务-蝉镜返回data字段为空，linkId={}", linkId);
                return;
            }
            CustomVoiceCjVo cjVo = objectMapper.treeToValue(dataNode, CustomVoiceCjVo.class);
            if (cjVo == null) {
                log.warn("定时任务-data字段转CustomVoiceCjVo失败，linkId={}", linkId);
                return;
            }

            if (cjVo.getStatus() != 1 && customVoice.getStatus() == 1) {
                // 需要更新
                // 更新字段
                customVoice.setName(cjVo.getName());
                customVoice.setAudioPath(cjVo.getAudio_path());
                customVoice.setStatus(cjVo.getStatus());
                customVoice.setLang(cjVo.getLang());
                customVoice.setErrMsg(cjVo.getErr_msg());
                customVoice.setProgress(cjVo.getProgress());
                customVoice.setUpdateTime(new Date());
                // type字段如果有可更新
                if (cjVo.getType() != null) customVoice.setType(cjVo.getType());

                customVoice.setUpdateTime(new Date());
                customVoiceService.updateById(customVoice);
                log.info("定时任务-定制声音状态已更新，linkId={}", linkId);

                // 确定事件名称
                String eventName;

                // status=2时异步上传OSS
                if (cjVo.getStatus() != null && cjVo.getStatus() == 2) {
                    eventName = WebSocketEventType.AddCustomVoiceSuccess.name();

                    // 异步上传OSS和更新数据库
                    customVoiceUrlUpdateTask.start(customVoice, cjVo);
                } else {
//                    eventName = "AddCustomVoiceFail";
                    eventName = WebSocketEventType.AddCustomVoiceFail.name();
                }

                // 推送WebSocket消息给前端
                Integer userId = customVoice.getUserId();
                if (userId != null) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("id", customVoice.getId());
                    data.put("linkId", cjVo.getId());
                    data.put("status", cjVo.getStatus());

                    Map<String, Object> message = new HashMap<>();
                    message.put("event", eventName);
                    message.put("data", data);

                    String jsonMessage = JSON.toJSONString(message);
                    webSocketSessionManager.sendMessageToUser(userId, jsonMessage);
                    log.info("向用户 {} 推送定制声音状态更新: {}", userId, jsonMessage);
                }

                return;
            }

            if (cjVo.getStatus() == 1 && customVoice.getStatus() == 1 && retryCount < 5) {
                log.info("定制声音未完成，1分钟后重试，linkId={}, retry={}", linkId, retryCount + 1);
                schedule(linkId, retryCount + 1);
            }
        } catch (Exception e) {
            log.error("定时任务-解析蝉镜返回数据异常，linkId={}", linkId, e);
        }
    }
} 